package de.hub.sar.itsec.sslfetcher;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import de.hub.sar.itsec.sslfetcher.clr.ArgReader;
import de.hub.sar.itsec.sslfetcher.clr.IntegerArgument;
import de.hub.sar.itsec.sslfetcher.clr.StringArgument;
import de.hub.sar.itsec.sslfetcher.hosts.FileHostProvider;
import de.hub.sar.itsec.sslfetcher.hosts.Host;
import de.hub.sar.itsec.sslfetcher.hosts.IHostsProvider;
import de.hub.sar.itsec.sslfetcher.log.Logger;
import de.hub.sar.itsec.sslfetcher.utils.Converter;


public class Main {
	private static final String ARG_OUT = "out";
	private static final String ARG_IN = "in";
	private static final String ARG_SOCKETS = "sockets";
	private static final String HOME_PATH = System.getProperty("user.home");
	private static final String DEFAULT_FOLDER = File.separator + "certfetcher";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ArgReader argReader;
		String id;
		long time;
		LoadListener listener;
		
		argReader = new ArgReader();
		argReader.add(new StringArgument(ARG_OUT, HOME_PATH + DEFAULT_FOLDER, null));
		argReader.add(new StringArgument(ARG_IN, null, null));
		argReader.add(new IntegerArgument(ARG_SOCKETS, 10, null));
		
		if (args.length == 1 && "help".equals(args[0])) {
			Logger.getInstance().info(argReader.getHelp());
			return;
		}
		
		argReader.scan(args);
		id = argReader.checkCompleteness();
		if (id != null) {
			Logger.getInstance().warn("The following argument is missing:\n" +
					argReader.getHelp(id));
			return;
		}
		
		// print info
		Logger.getInstance().info("Hosts:       " + argReader.getStringValue(ARG_IN));
		Logger.getInstance().info("Output:      " + argReader.getStringValue(ARG_OUT));
		Logger.getInstance().info("Connections: " + argReader.getIntValue(ARG_SOCKETS));
		Logger.getInstance().line();
		
		// run
		time = System.currentTimeMillis();
		listener = new LoadListener();
		run(argReader, listener);
		
		// print timings
		time = System.currentTimeMillis() - time;
		Logger.getInstance().line();
		Logger.getInstance().info("Finished after " + Converter.millisToString(time));
		Logger.getInstance().info("Total saved certificates: " + listener.countDone() + " of " + listener.count());
		Logger.getInstance().info("Per second: " + (int) (listener.count() / ((double) time / 1000)));
	}
	
	private static void run(final ArgReader argReader, 
			final ILoadListener listener) {
		IHostsProvider hosts;
		ExecutorService execService;
		
		execService = new LoaderThreadPoolExecuter( 
				argReader.getIntValue(ARG_SOCKETS),
                new LoaderThreadFactory(argReader.getStringValue(ARG_OUT)));
		
		try {
			hosts = new FileHostProvider(argReader.getStringValue(ARG_IN));
		} catch (FileNotFoundException e) {
			Logger.getInstance().error(e.getMessage());
			return;
		}
		
		for (Host host : hosts) {
			execService.execute(new LoadRunner(host, listener));
		}
		
		// wait for termination
		execService.shutdown();
		try {
			execService.awaitTermination(1, TimeUnit.MINUTES);
		} catch (InterruptedException e) {
		}
	}
}
